

namespace Core.Features
{
    using System;
    using Base;
    using Contracts.Enums;
    using Resources;
    using Contracts.Interfaces;
    using System.Linq;

    
    public sealed class AccumulatorRechargeTime<T> : FeatureBase<object>
    {
        public AccumulatorRechargeTime(){}

        public AccumulatorRechargeTime(T value) 
            : base(value){ }

        /// <summary>
        /// Obtains the feature name
        /// </summary>
        public override string Name
        {
            get { return "Accumulator recharge time"; }
        }

        /// <summary>
        /// Obtains the feature group
        /// </summary>
        public override FeatureGroupsEnum FeatureGroup{ get { return FeatureGroupsEnum.Engine; } }
        /// <summary>
        /// Obtains the feature type
        /// </summary>
        public override FeaturesEnum FeatureType { get { return FeaturesEnum.AccumulatorRechargeTime; } }
        /// <summary>
        /// Obtains or defines the feature unit
        /// </summary>
        public override string Unit { get { return Traduction.label_unit_sec; } }

        /// <summary>
        /// Determines if the feature value is rounded
        /// </summary>
        public override bool IsRounded
        {
            get { return true; }
        }

        public override void SetModifiedValue(IAgent agent, IRobot robot)
        {
            if (agent == null || robot == null) return;

            // Extensions
            double temp = (double)Value * (1 - agent.Extensions.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType));

            // Bonus from bots (ex: Castel)
            double botBonus = 0;
            foreach (var bonusModifier in robot.Modifiers.Where(b => b.ModifiedFeatureType == FeatureTypesEnum.Robot && Equals(b.Feature, this.FeatureType)))
            {
                var bmod = bonusModifier;
                var bextension = agent.Extensions.Where(e => Equals(bmod.Extension, e)).FirstOrDefault();
                if (bextension == null) continue;

                botBonus += Math.Abs(bmod.Value) * bextension.Level;
            }

            temp *= (1 - botBonus);

            // Rechargers modules
            foreach (var module in robot.Modules.Where(m => m.Group == ModuleGroupsEnum.AccumulatorRechargers && m.Modifiers != null && m.Modifiers.Any()))
            {
                var mods = module.Modifiers.Where(m => m.ModifiedFeatureType == FeatureTypesEnum.Robot && m.Feature == this.FeatureType);
                if (!mods.Any()) continue;

                temp = mods.Aggregate(temp, (current, modifier) => current * (1 - Math.Abs(modifier.Value)));
            }

            // RangeExtenders
            foreach (var module in robot.Modules.Where(m => m.Group == ModuleGroupsEnum.RangeExtenders && m.Modifiers != null && m.Modifiers.Any()))
            {
                var mods = module.Modifiers.Where(m => m.ModifiedFeatureType == FeatureTypesEnum.Robot && m.Feature == this.FeatureType);
                if (!mods.Any()) continue;

                temp = mods.Aggregate(temp, (current, modifier) => current * (1 + Math.Abs(modifier.Value)));
            }

            ModifiedValue = IsRounded
                               ? Math.Round(temp, 0, MidpointRounding.AwayFromZero)
                               : Math.Round(temp, 2);
        }
        
    }
}